#pragma once
#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>


const std::string gpath = "/home/dpj/";
int gprojId = 66666;
const int gsize = 4096;

struct data 
{
    int type;
    char text[gsize];
};


std::string ToHex(int k)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%x", k);
    return buffer;
}

class ShareMemory
{
public:
    ShareMemory()
        : _k(-1), _shmid(-1), _ret(nullptr)
    {
        
    }
    void GetKey()
    {
        _k = ::ftok(gpath.c_str(), gprojId);
        if (_k < 0)
        {
            std::cout << "ftok error" << std::endl;
            return;
        }
        std::cout << "ftok done..." << std::endl;
        std::cout << "key: " << ToHex(_k) << std::endl;
    }
    void CreateShm()
    {
        _shmid = OpenShm(IPC_CREAT | IPC_EXCL | 0600);
    }
    void ShmMeta()
    {
        struct shmid_ds buffer;
        ::shmctl(_shmid,IPC_STAT,&buffer);
        std::cout << "##########################" << std::endl;
        std::cout << buffer.shm_atime << std::endl;
        std::cout << buffer.shm_nattch << std::endl;
        std::cout << buffer.shm_cpid << std::endl;
        std::cout << ToHex(buffer.shm_perm.__key) << std::endl;
        std::cout << "##########################" << std::endl;

    }
    void ObtainShm()
    {
        _shmid = OpenShm(IPC_CREAT);
    }
    void* GetAddr()
    {
        return _ret;
    }
    void CreatAtch()
    {
        _ret = shmat(_shmid, nullptr, 0);
        std::cout << "shmat return: " << (long long)_ret << std::endl;
        std::cout << "shmat done..." << std::endl;
    }
    void DeleteAtch()
    {
        int n = shmdt(_ret);
        std::cout << "shmdt done..." << std::endl;
        if (n < 0)
        {
            std::cout << "shmdt error" << std::endl;
        }
    }
    void DestoryShm()
    {
        ::shmctl(_shmid, IPC_RMID, nullptr); // 代码销毁共享内存
        std::cout << "sever shmctl done..." << std::endl;
    }
    ~ShareMemory()
    {}
private:
    int OpenShm(int flg)
    {
        int shmid = ::shmget(_k, gsize, flg);
        std::cout << "shmget done..." << std::endl;
        if (shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return -1;
        }
        std::cout << "shmid: " << shmid << std::endl;
        return shmid;
    }
    key_t _k;
    int _shmid;
    void *_ret;
};
